usingnamespace @import("std");
usingnamespace @import("util");
usingnamespace @cImport({
    @cInclude("xcb/xcb.h");
    @cInclude("xcb/xproto.h");
});

const Self = @This();

const XcbEvents = struct {
    elem: ?*Self.xcb_generic_event_t,
    node: Self.DoublyLinkedList.Node = .{},
};

var gpa: Self.heap.GeneralPurposeAllocator(.{}) = .init;
const allocator = gpa.allocator();

mutex: Self.Thread.Mutex = .{},
queue: Self.DoublyLinkedList = .{},

///创建队列节点
pub fn create(_: *Self, elem: ?*Self.xcb_generic_event_t) Self.WmErr!*XcbEvents {
    const node = allocator.create(XcbEvents) catch {
        return error.AllocatedMemoryFail;
    };
    node.elem = elem;

    return node;
}

///销毁队列节点
pub fn destroy(_: *Self, evq: *XcbEvents) void {
    if (evq.elem) |e| {
        Self.c.free(e);
    }
    allocator.destroy(evq);
}

///将事件添加到队列
pub fn enqueue(self: *Self, evq: *XcbEvents) void {
    self.mutex.lock();
    defer self.mutex.unlock();
    self.queue.append(&evq.node);
}

///从队列取出事件
pub fn dequeue(self: *Self) ?*XcbEvents {
    self.mutex.lock();
    defer self.mutex.unlock();

    const node = self.queue.pop() orelse return null;
    const e: *XcbEvents = @fieldParentPtr("node", node);
    return e;
}

///判断队列是否为空
pub fn isEmpty(self: *Self) bool {
    return self.queue.first == self.queue.last;
}

///销毁队列
pub fn deinit(self: *Self) void {
    var it = self.queue.pop();
    while (it) |node| {
        const e: *XcbEvents = @fieldParentPtr("node", node);
        destroy(e);
        it = self.queue.pop();
    }
}
